#include "udp_client.hpp"
#include <iostream>
#include <cstring>
#include <cerrno>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <strings.h>
#include "err.hpp"

using namespace std;

static void usage(string proc)
{
    cout << "Usage:\n\t" << proc << " server_ip server_port\n" << endl;
}

// 127.0.0.1: 本地环回，表示当前主机，通常用来进行本地通信或者测试

int main(int argc, char *argv[])
{
    if(argc != 3)
    {
        usage(argv[0]);
        exit(USAGE_ERR);
    }
    string server_ip = argv[1];
    uint16_t server_port = atoi(argv[2]);

    int sock = socket(AF_INET, SOCK_DGRAM, 0);
    if(sock < 0)
    {
        cerr << "创建套接字失败" << endl;
        exit(SOCKET_ERR);
    }

    // client的port由OS分配防止client启动冲突

    // 明确server
    struct sockaddr_in server;
    memset(&server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = inet_addr(server_ip.c_str());
    server.sin_port = htons(server_port);

    while(1)
    {
        string message;
        cout << "发：";
        getline(cin, message);

        // 首次调用OS发送数据时，OS会在底层随机选择client_port + 自己的ip，构建发送的数据报文
        // 发送
        sendto(sock, message.c_str(), message.size(), 0, (struct sockaddr*)&server, sizeof(server));

        // 接收
        char buffer[1024];
        struct sockaddr_in temp;
        socklen_t len = sizeof(temp);
        int n = recvfrom(sock, buffer, sizeof(buffer) - 1, 0, (struct sockaddr*)&temp, &len);
        if(n > 0)
        {
            buffer[n] = 0;
            cout << "收：" << buffer << endl;
        }
    }

    return 0;
}